<?php

namespace app\uapi\controller;

use app\admin\model\KnscyGoods;
use app\admin\model\KnscyOrderLogs;
use app\admin\model\KnscyOrders;
use app\admin\model\KnscyOrderTicket;
use app\admin\model\KnscyRedpackAgent;
use app\admin\model\KnscyTicketOut;
use app\admin\model\KnscyTicketOutLogs;
use app\admin\model\KnscyTickets;
use app\admin\model\KnscyUserPeople;
use app\admin\model\KnscyUsers;
use app\common\controller\ApiController;
use app\common\service\GoodService;
use app\common\service\OrderService;
use app\common\service\TicketPriceService;
use app\common\service\UserService;
use app\common\service\WeginService;
use think\facade\Db;

class Order extends ApiController
{
    public static $needLoginAction = [
        'userOrderList',
        'createOrder',
        'orderDetail',
        'qrcodeOrder', //核销订单
        'refundOrder', //订单退款
        'qrcodeTicketOut', //核销门票/卡
    ];

    /**
     * 检测当前时间是否允许购票
     * @return void
     */
    public function verifyTime()
    {
        $ticket_id = $this->request->post('ticket_id');
        $day_select = $this->request->post('day_select');
        $ticket = KnscyTickets::where('id', $ticket_id)->find();
        if (empty($ticket)) {
            $this->error('参数错误');
        }

        if ($ticket->min_time) {

            $date2 = new \DateTime($day_select . date('H:i:s'));
            $date1 = new \DateTime(date('Y-m-d 17:00:00'));
            // 计算时间差
            $interval = $date2->diff($date1);
            // 获取相差的小时数
            $hours = $interval->h + ($interval->d * 24);
            if ($hours < $ticket->min_time) {
                $this->error('需要提前' . $ticket->min_time . '小时购买');
            }

        }
        $this->success('success');
    }

    /**
     * 前端提交数据创建订单
     * buy_num: 1
     * day_select: "2024-12-04"
     * money: "22"
     * people_ids: "17"
     * price: "22"
     * remark: ""
     * ticket_id: 21
     * @return void
     */
    public function createOrder()
    {
        $post = $this->request->post();
        $rules = [
            'buy_num|购买数量' => 'require',
            'day_select|出游日期' => 'require',
            'ticket_id|门票ID' => 'require',
            'good_id|商品ID' => 'require',
        ];
        $ticket = KnscyTickets::where('id', $post['ticket_id'])->find();
        $good = KnscyGoods::where('id', $post['good_id'])->find();
        if (empty($ticket) || empty($good)) {
            $this->error('参数错误');
        }
        //验证选择今天超过了最后购票时间
        if(strtotime($post['day_select']) <  strtotime(TicketPriceService::get_start_day())) {
            $this->error('今日不能购票');
        }

        //验证价格是否正确
        $ticket_price = TicketPriceService::getdayPrice($post['day_select'], $post['ticket_id']);
        if ($ticket_price != $post['price']) {
            $this->error('价格参数有误' );
        }
        $total_price = $ticket_price * $post['buy_num'];
        $this->validate($post, $rules);


        $order = new knscyOrders();
        //采用事务
        $order->startTrans();
        try {

            $post['uniacid'] = WeginService::getUniacid();
            $post['user_id'] = $this->user_id;
            $post['status_label'] = 'unpaid';
            $post['order_money'] = $total_price ;
            $post['order_no'] = OrderService::order_gen_id();
            //预留折扣优惠,可以加入折扣值
            $discount_money = OrderService::get_discount_detail($post['agent_sn'], $this->user_id);
            if($discount_money > $total_price){
                $post['discount_money'] = $total_price;
            } else{
                $post['discount_money'] = $discount_money;
            }
             //换票和退票
            $post['need_check'] = $ticket['need_check'];
            $post['can_refund'] = $ticket['can_refund'];
            //门票-次卡-年卡
            $post['ticket_type'] = $ticket['ticket_type'];
            $post['good_title'] = $good['title']; //商品标题

            $order->save($post);

            $peoples = [];
            if ($post['people_ids']) {
                $peoples = KnscyUserPeople::whereIn('id', $post['people_ids'])
                    ->field('id,first_name,name,mobile,identity,identity_type')
                    ->select();

            }
            //添加门票记录
            $order_detail = [
                'order_no' => $order['order_no'],
                'order_id' => $order['id'],
                'uniacid' => $order['uniacid'],
                'ticket_type'  => $ticket['ticket_type'],
                'ticket_id' => $ticket['id'],
                'ticket_title' => $ticket['title'],
                'ticket_subtitle' => $ticket['sub_title'],
                'good_id' => $good['id'],
                'good_title' => $good['title'],
                'select_day' => $post['day_select'],
                'buy_num' => $post['buy_num'],
                'price' => $post['price'],
                'people_ids' => $post['people_ids'],
                'people_json' => json_encode($peoples),
                'ticket_json' => json_encode($ticket)
            ];
            KnscyOrderTicket::create($order_detail);
            //创建日志
            KnscyOrderLogs::create([
                'uniacid' => $order['uniacid'],
                'order_id' => $order['id'],
                'order_no' => $order['order_no'],
                'tag' => 'order.createOrder',
                'content' => 'createOrder => 创建订单',
            ]);
            //相关都创建结束，订单数据生效
            KnscyOrders::where('id', $order['id'])->update(['order_status' => 1]);
            $orm  = KnscyOrders::where('id', $order['id'])->find();
            //创建相关出票零时数据
            OrderService::createTicketOut($orm, $order_detail);
            //如果折扣后价格=0 改变订单状态
            OrderService::directBuy($orm);
            //增加门票的销量
            KnscyTickets::where('id', $post['ticket_id'])
                ->update(['sale_count' => Db::raw('sale_count+'.$post['buy_num'])]);
            //有使用了优惠券的改变优惠券状态
            OrderService::order_use_discount($post['agent_sn'], $this->user_id, $order );

            //事务提交sql
            $order->commit();


        } catch (\Exception $e) {
            $order->rollback();
            $this->error($e->getMessage());
        }

        $this->success('success', $order);
    }

    public function orderDetail()
    {
        $id = $this->request->post('id');
        $order = KnscyOrders::where('id', $id)->field("*,order_money as total_price")->find();
        if (empty($order)) {
            $this->error('error');
        }
        $this->format_order($order);
        $detail = KnscyOrderTicket::where('order_id', $order['id'])->find();
        if (empty($detail)) {
            $this->error('error');
        }
        $ticket =  $detail['ticket_json'] ;
        $ticket['address'] = sysconfig('company', 'address') ?? '请设置门票地址';
        //关联 的文案
        $ticket['remark_list'] = GoodService::ticketInfos($ticket['remark']);
        //
        $peoples =  $detail['people_json'] ;

        $this->success('success', [
            'order' => $order,
            'detail' => $detail,
            'ticket' => $ticket,
            'peoples' => $peoples,
        ]);
    }

    /**
     * 用户的订单列表
     * @return void
     */
    public function userOrderList()
    {
        $limit = $this->request->post('limit', 10);
        $page = $this->request->post('page', 1);
        $status_label = $this->request->post('status', '');


        $label = array_keys(KnscyOrders::statusLabels());
        if (!in_array($status_label, $label)) {
            $status_label = 'all';
        }

        //订单查询
        $datalist = KnscyOrders::withoutGlobalScope(['uniacid'])->alias('o')
            ->where('o.uniacid', WeginService::getUniacid())
            ->where('user_id', $this->user_id)
            ->when($status_label !== 'all', function ($query) use ($status_label) {
                $query->where('status_label', $status_label);
            })
            ->leftjoin(KnscyOrderTicket::getTable() . " t ", "t.order_id = o.id")
            //订单的total_price是模型的属性，通过别名查询可以获取属性值
            ->field("o.*,o.order_money as total_price, t.ticket_title,t.ticket_subtitle,t.good_title,t.select_day,t.buy_num,t.price,t.ticket_json ")
            ->order(Db::raw('o.sort=0,o.sort asc,o.id desc'))
            ->paginate(
                [
                    'list_rows' => $limit,
                    'page' => $page,
                ]
            )->each(function ($item) {
                $this->format_order($item);
                $ticket = json_decode($item['ticket_json'], true);
                $item['use_count']  =  $ticket['use_count'] ?? 0;
                $item['use_count_label'] = '次卡显示此次数，门票和年卡不用来判断';

            });
        $this->success('success', $datalist);
    }

    /**
     * @param KnscyOrders $item 是 KnscyOrders实例
     * @return void
     */
    protected function format_order(&$item)
    {
        $item->time_label = date('Y-m-d H:i', strtotime($item->create_time));
        $item->status_label_txt = KnscyOrders::statusLabels($item->status_label);
        $item['unpaid'] = $item->is_not_paid;
        //核销码的内容
        $item['qrcode_value'] = "verifyOrderNo=" . $item->order_no;
        //判断是否可以退款
        $item['can_online_refund'] = OrderService::isCanRefund($item);
        $ticket_types = KnscyTickets::getTicketTypeList();
        $item['ticket_type_label'] = $ticket_types[$item->ticket_type] ?? '门票';


    }

    /**
     * 核销门票/年卡次卡
     * @return void
     */
    protected function qrcodeTicketOut($qrcode)
    {
        $arr = explode('=', $qrcode);
        $ticket_sn = $arr[1] ?? '';
        $user = KnscyUsers::find($this->user_id);
        if (empty($user) || $user->ishexiao != 1) {
            $this->error('无操作权限',[],1);
        }
        $ticket_out = KnscyTicketOut::where('ticket_sn', $ticket_sn)
            ->whereTime('end_time',">=", time())->find();
        if (empty($ticket_out)) {
            $this->error('门票（或卡）数据不存在',[],1);
        }
        if($ticket_out['is_end']==1){
            $this->error('已经使用完',[],1);
        }
        $log = KnscyTicketOutLogs::where('ticket_sn', $ticket_sn)
            ->whereTime('create_time','>', strtotime('-10 minutes'))->find();
        if (!empty($log)) {
            $this->error('今日已经有使用记录',[],1);
        }
        KnscyTicketOutLogs::create([
            'ticket_sn'=> $ticket_out['ticket_sn'],
            'uniacid' =>  $ticket_out['uniacid'],
            'ticket_type' => $ticket_out['ticket_type'],
            'hx_user_id' => $this->user_id,
            'tag'=> 'order:qrcodeTicketOut',
        ]);
        //订单核销处理门票逻辑
        $update = [
            'use_count'=> Db::raw('use_count+1'),
            'last_use_time' => date('Y-m-d H:i:s' ),
        ];
        //检查是否用完
        if($ticket_out['ticket_type'] !== 3){
            //非年卡的时候 次数满了要结束
            if($ticket_out['use_count']  + 1 >= $ticket_out['total_count']){
                $update['is_end'] = 1;
            }
        }

        KnscyTicketOut::update( $update, ['id' => $ticket_out['id']]);

        $this->success('success', ['type'=> 'ticket_out', 'data'=> $ticket_out]);
    }

    public function qrcodeOrder()
    {
        $user = KnscyUsers::find($this->user_id);
        if (empty($user) || $user->ishexiao != 1) {
            $this->error('无操作权限',[],1);
        }

        $qrcode = $this->request->post('qrcode', '');
        //核销订单
        if (preg_match('/verifyOrderNo=/', $qrcode)) {
            $this->verifyOrderNo($qrcode);
            return;
        }
        //核销门票
        if (preg_match('/ticketOutQrcode=/', $qrcode)) {
             $this->qrcodeTicketOut($qrcode);
             return;
        }
        //核销优惠券的线下凭证
        if(preg_match('/verifyRedPack=/', $qrcode)){
            $this->qrcodeCouponAgentSn($qrcode);
            return;
        }
        $this->error('核销码有误',[],1);
    }

    /**
     * 扫码核销线下凭证
     * @param $qrcode
     * @return void
     */
    protected  function qrcodeCouponAgentSn($qrcode)
    {
        $arr = explode('=', $qrcode);
        $agent_sn = $arr[1] ?? '';
        $agent = KnscyRedpackAgent::where('agent_sn', $agent_sn)->find();
        if (empty($agent)) {
            $this->error('线下凭证数据不存在',[],1);
        }
        //验证是否使用
        if($agent['is_used']==1){
            $this->error('线下凭证已使用过',[],1);
        }
        //查看是否有日志
        $log = KnscyTicketOutLogs::where('ticket_sn', $agent_sn)->find();
        if(!empty($log)){
            $this->error('线下凭证已使用过了',[],1);
        }
        //检测是否过期
        if(strtotime($agent['end_time']) < time()){
            $this->error('线下凭证过期失效了',[],1);
        }
        KnscyTicketOutLogs::create([
            'ticket_sn'=> $agent['agent_sn'],
            'uniacid' =>  $agent['uniacid'],
            'ticket_type' => $agent['redpack_type'],
            'hx_user_id' => $this->user_id,
            'tag'=> 'order:qrcodeCouponAgentSn',
        ]);
        //订单核销处理门票逻辑
        $update = [
            'is_used'=> 1,
            'use_time' => date('Y-m-d H:i:s' ),
        ];
        KnscyRedpackAgent::update($update, ['id'=> $agent['id']]);

        $this->success('核销成功', ['type'=> 'redpack','data'=> $agent]);
    }

    /**
     * 扫码核销订单功能
     */
    protected function verifyOrderNo($qrcode)
    {

        $arr = explode('=', $qrcode);
        $order_no = $arr[1] ?? '';

        $user = KnscyUsers::find($this->user_id);
        if (empty($user) || $user->ishexiao != 1) {
            $this->error('无操作权限',[],1);
        }

        $order = KnscyOrders::where('order_no', $order_no)->find();
        if (empty($order)) {
            $this->error('订单数据不存在',[],1);
        }
        if ($order->status_label != 'process') {
            $txt = KnscyOrders::statusLabels( $order->status_label);
            $this->error('操作失败：订单'.$txt , $order ,1);
        }
        //如果是门票，检测出行日期是否是当日
        $day = date('Y-m-d');
        $ticket = KnscyOrderTicket::where('order_id', $order['id'])->find();
        if(empty($ticket)){
            $this->error('没有门票信息',[],1);
        }
        if($order['ticket_type']==1){
            if (empty($ticket) || $day != $ticket['select_day']) {
                $this->error('出行日期不正确',[],1);
            }
        }

        $oldOrder = clone $order;
        //更改订单状态
        $order->status_label = 'completed';
        $order->order_status = KnscyOrders::label2Status('completed');
        $order->save();
        OrderService::changeStatus($order, $oldOrder, 'order.qrcode.check');
        //订单核销处理门票逻辑
        $update = [
            'use_count'=> Db::raw('use_count+1'),
            'last_use_time' => date('Y-m-d H:i:s' ),
        ];

        if($order->ticket_type==1){
            $update['is_end'] = 1;
            $update['end_time'] = date('Y-m-d H:i:s' );
        }else{
            $update['sort'] = 1; //扫码订单激活了卡
            $update['end_time'] = date('Y-m-d H:i:s', strtotime('+1 year'));
        }
        KnscyTicketOut::update($update, ['order_no' => $order['order_no']]);
        //把出票记录使用
        $ticket_outs = KnscyTicketOut::where('order_no', $order['order_no'])->select();
        foreach($ticket_outs as $ticket_out){
            KnscyTicketOutLogs::create([
                'ticket_sn'=> $ticket_out['ticket_sn'],
                'uniacid' =>  $ticket_out['uniacid'],
                'ticket_type' => $ticket_out['ticket_type'],
                'hx_user_id' => $this->user_id,
                'tag'=> 'order:qrcodeOrder',
            ]);
        }


        $this->success('success', ['type'=>'order', 'data'=> $order]);
    }

    /**
     * 申请退款操作 需要登录
     * @return void
     */
    public function refundOrder()
    {
        $orderNo = $this->request->post('orderNo');
        $order = KnscyOrders::where('order_no', $orderNo)
            ->where('user_id', $this->user_id)->find();
        if (!$order) {
            $this->error('参数错误');
        }
        //首先load模块函数
        load()->model('refund');
        //待出行的订单才能付款 必须是通过在线付款的通道才能退款
        if (!OrderService::isCanRefund($order)) {
            $this->error('此订单不能申请退款');
        }
        //创建退款订单
        OrderService::orderDoRefund($order);
        //$tid  模块内订单id
        $tid = $order['order_no'];
        //$module 需要退款的模块
        $module = 'kbwdl_nickscenery';
        //$fee 退款金额
        $fee = $order['pay_money'];
        //$reason 退款原因
        $reason = '客户主动申请退款';
        //成功返回退款单id，失败返回error结构错误
        $refund_id = refund_create_order($tid, $module, $fee, $reason);
        if (is_error($refund_id)) {
            $this->error($refund_id['message']);

        }
        //发起退款
        $refund_result = refund($refund_id);
        if (is_error($refund_result)) {
            $this->error($refund_result['message']);

        } else {
            pdo_update('core_refundlog', array('status' => 1), array('id' => $refund_id));
            //XXX（这里继续写自己的其他逻辑）
            OrderService::orderDoRefund($order);
            $this->success('退款成功');
        }
    }
}